package com.cd2cd.code_template.curd.controller;

import com.alibaba.fastjson.JSONObject;
import com.cd2cd.code_template.configuration.constants.ServiceCode;
import com.cd2cd.code_template.curd.config.CURDConfig;
import com.cd2cd.code_template.curd.service.DispatchService;
import com.cd2cd.code_template.vo.BaseRes;
import com.cd2cd.code_template.vo.PageData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import static com.cd2cd.code_template.curd.service.CurdEnum.*;

/**
 * 1、表数据查询会涉及到多表关系联查问题；
 * 2、请求数据参数验证问题
 * 3、返回数据置空
 * 4、表关联数据
 */
@Slf4j
@Controller
@RequestMapping(CURDConfig.CURD_REQUEST_URL)
public class CURDController {

    private Logger LOG = LoggerFactory.getLogger(CURDController.class);

    @Resource
    private DispatchService dispatchService;

    private Map<String, Object> getRequestParams(HttpServletRequest request) {
        Enumeration<String> parameters = request.getParameterNames();
        Map<String, Object> params = new HashMap<>();

        while (parameters.hasMoreElements()) {
            String name = parameters.nextElement();
            params.put(name, request.getParameter(name));
        }

        try {
            // 获取 payload内的数据
            InputStream is = request.getInputStream();
            int aNum = is.available();
            LOG.info("aNum={}", aNum);
            if (aNum > 0) {

                String ss = IOUtils.toString(is, "utf-8");
                LOG.info("ss={}", ss);

                Map<String, Object> pp = JSONObject.parseObject(ss, Map.class);

                params.putAll(pp);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return params;
    }

    /**
     * ignore: 不显示字段；使用逗号隔开
     *
     * @param entity
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping("{entity}/page")
    public BaseRes<PageData<Object>> entityPage(@PathVariable("entity") String entity, HttpServletRequest request) {
        Boolean l = CURDConfig.testEnable(entity, "l");
        if (!l) {
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        return dispatchService.dispatch(entityPage, entity, params);
    }

    /**
     * ignore: 不显示字段；使用逗号隔开
     *
     * @param entity
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "{entity}/info", method = RequestMethod.GET)
    public BaseRes<Object> entityInfo(@PathVariable("entity") String entity, HttpServletRequest request) {

        Boolean r = CURDConfig.testEnable(entity, "r");

        if (!r) {
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        return dispatchService.dispatch(entityInfo, entity, params);
    }

    /**
     * 更新表字段
     *
     * @param entity
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "{entity}/info", method = RequestMethod.PUT)
    public BaseRes<Object> entityUpdate(@PathVariable("entity") String entity, HttpServletRequest request) {

        Boolean u = CURDConfig.testEnable(entity, "u");

        if (!u) {
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        return dispatchService.dispatch(entityUpdate, entity, params);
    }

    /**
     * 添加表字段
     *
     * @param entity
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "{entity}/info", method = RequestMethod.POST)
    public BaseRes<Object> entityAdd(@PathVariable("entity") String entity, HttpServletRequest request) {

        Boolean c = CURDConfig.testEnable(entity, "c");

        if (!c) {
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        return dispatchService.dispatch(entityAdd, entity, params);
    }

    @ResponseBody
    @RequestMapping(value = "{entity}/info", method = RequestMethod.DELETE)
    public BaseRes<Object> entityDel(@PathVariable("entity") String entity, HttpServletRequest request) {

        Boolean d = CURDConfig.testEnable(entity, "d");

        if (!d) {
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        return dispatchService.dispatch(entityDel, entity, params);
    }

    /**
     * @param entity 表名 domain java 对应数据库表名称
     * @param foreignKey 外键字段 java成员变量名 project_id: projectId
     *                   调用例子: http://ip:port/project/curd/{doMain}/{foreignKey}
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "{entity}/dic/{foreignKey}", method = RequestMethod.GET)
    public BaseRes<Object> dynamicDic(@PathVariable("entity") String entity, @PathVariable("foreignKey") String foreignKey, HttpServletRequest request) {

        Boolean d = CURDConfig.testEnable(entity, "re", foreignKey);
        if (!d) {
            log.error("t={}, f={}, testEnable->false", entity, foreignKey);
            return new BaseRes<>(ServiceCode.ACCESS_DENIED);
        }

        Map<String, Object> params = getRequestParams(request);
        params.put("foreignKey", foreignKey);
        return dispatchService.dispatch(dynamicDic, entity, params);
    }

}
